<template>
  <div class="container">
    <header class="header flex-vertical-center flex-row-reverse">
      <a-dropdown v-if="token && username">
        <div class="pr-normal">
          <span class="username">{{ username }}</span>
        </div>
        <a-menu slot="overlay">
          <a-menu-item @click="logout">
            <a href="javascript:;">退出登录</a>
          </a-menu-item>
          <a-menu-item @click="goToHistory">
            <a href="javascript:;">历史记录</a>
          </a-menu-item>
          <a-menu-item @click="createConversation(false)">
            <a href="javascript:;">新建对话</a>
          </a-menu-item>
          <a-menu-item @click="info">
            <a href="javascript:;">联系开发者</a>
          </a-menu-item>
        </a-menu>
      </a-dropdown>
      <a-dropdown v-else>
        <div class="flex-vertical-center pr-normal">
          <span class="username" @click="goToLogin">登录</span>
        </div>
        <a-menu slot="overlay">
          <a-menu-item @click="info">
            <a href="javascript:;">联系开发者</a>
          </a-menu-item>
        </a-menu>
      </a-dropdown>
    </header>
    <main class="main" v-if="token && username">
      <div class="main__inner flex-center" v-if="!isCreateConversation">
        <a-button type="primary" class="mr-normal" @click="createConversation" :loading="loading">
          新建对话
        </a-button>
        <a-button type="primary" @click="goToHistory">
          查看历史对话
        </a-button>
      </div>
      <div class="main__inner" v-if="isCreateConversation" ref="mainInner">
        <div id="container-list">
          <a-list item-layout="horizontal" :data-source="list">
            <a-list-item slot="renderItem" slot-scope="item, index">
              <div class="flex">
                <template>
                  <img v-if="item.receiver_id === 0" class="main-image" src="../assets/images/personal.png" />
                  <img v-else class="main-image" src="../assets/images/logo.svg" />
                </template>
                <template>
                  <span style="white-space: pre-line" v-if="!isLoading && isGptAnswerMe && index === list.length - 1">{{ noviceText }} <span class="animate">|</span> </span>
                  <span v-else-if="isLoading && isGptAnswerMe && index === list.length - 1" class="loading"><span class="dot">...</span> </span>
                  <span style="white-space: pre-line" v-else>
                    {{ item.content }}
                  </span>
                </template>
              </div>
            </a-list-item>
          </a-list>
        </div>
      </div>
    </main>
    <footer class="footer p-normal" v-if="token && username && isCreateConversation">
      <a-input placeholder="请输入对话内容" :value="message" @change="onChange" @pressEnter="pressEnter" />
    </footer>
  </div>
</template>

<script>
import {newChat, userLogOut, getChatMessages} from '@/utils/chat'
import { mapState } from 'vuex'
export default {
  name: 'ChatHome',
  components: {

  },
  data() {
    return {
      list: [],
      message: '',
      conversation_id: '',

      isCreateConversation: false,

      loading: false,

      typingTime: null,
      noviceText: '',

      isGptAnswerMe: false,
      isLoading: false,
    }
  },
  computed: mapState([
    'username',
    'token'
  ]),
  watch: {
    list: {
      handler(newVal, oldVal) {
        this.isGptAnswerMe && this.$nextTick(() => {
          console.log(newVal, oldVal)
          var h = document.getElementById('container-list').offsetHeight
          console.log('h', h)
          // var container_h = document.getElementById('main-inner').offsetHeight
          this.$refs.mainInner.scrollTo({ top: h, behavior: 'smooth' })
        })
      },
      deep: true
    },
    "noviceText": {
      handler(newVal, oldVal) {
        this.$nextTick(() => {
          console.log(newVal, oldVal)
          var h = document.getElementById('container-list').offsetHeight
          // var container_h = document.getElementById('main-inner').offsetHeight
          this.$refs.mainInner.scrollTo({ top: h, behavior: 'smooth' })
        })
      }
    }
  },
  created() {

  },
  mounted() {
    const conversation_id = this.$route && this.$route.query && this.$route.query.conversation_id ? this.$route.query.conversation_id : ''

    // const deleteConversation = window.localStorage.getItem('deleteConversation') ? JSON.parse(window.localStorage.getItem('deleteConversation')) : null

    // if(deleteConversation && (deleteConversation.conversation_id === conversation_id || deleteConversation.isDeleteAll)) {
    //   return
    // }

    if(conversation_id) {
      this.conversation_id = conversation_id
      this.isCreateConversation = true

      getChatMessages({
        conversation_id: conversation_id
      }).then(res => {
        this.list = res.data
      }).catch(err => {
        console.log('err', err)
      })
    }
  },
  methods: {
    info() {
      this.$info({
        title: '联系开发者',
        content: (
          <div>
            <p>如果您有遇到bug或者有什么优化建议，欢迎给我发邮件</p>
            <p>我的邮箱2498727035@qq.com</p>
          </div>
        ),
      });
    },

    pressEnter(e) {
      let isGptAnswerMe = this.isGptAnswerMe
      if (isGptAnswerMe) {
        return
      }
      this.isGptAnswerMe = true
      const { value } = e.target;
      
      let params = {
        user_message: value,
        conversation_id: this.conversation_id
      }

      let list = this.list
      list.push({
        content: value,
        receiver_id: 0
      })
      list.push({
        content: '',
      })
      console.log('params', params)

      // var h = document.getElementById('container-list').offsetHeight
      // // var container_h = document.getElementById('main-inner').offsetHeight
      // this.$refs.mainInner.scrollTo({ top: h, behavior: 'smooth' })

      this.message = ''
      this.list = list
      this.isLoading = true
      let that = this
      this.noviceText = ""

      const myHeaders = new Headers();
      const token = this.token
      if (token) {
        myHeaders.append("auth", token);
        myHeaders.append("Content-Type", "application/json");
      }
      fetch("http://api.ailanding.club/send_message_stream", {
        method: 'POST',
        headers: myHeaders,
        body: JSON.stringify(params)
      })
      // Retrieve its body as ReadableStream
      .then((response) => {
        const reader = response.body.getReader();
        reader.read().then(function pump({ done, value }) {
          that.isLoading = false
          if (done) {
            let list = that.list
            list.splice(list.length - 1, 1, {
              content: that.noviceText
            })
            that.list = list
            that.noviceText = ""
            that.isGptAnswerMe = false
            return;
          }
          console.log('value', that.Decodeuint8arr(value))
          that.noviceText = that.noviceText + that.Decodeuint8arr(value)

          return reader.read().then(pump);
        });
      })
      .catch((err) => console.error(err));
      return
    },

    /**
     * Convert an Uint8Array into a string.
     *
     * @returns {String}
     */
    Decodeuint8arr(uint8array){
        return new TextDecoder("utf-8").decode(uint8array);
    },

    /**
     * Convert a string into a Uint8Array.
     *
     * @returns {Uint8Array}
     */
    Encodeuint8arr(myString){
      return new TextEncoder("utf-8").encode(myString);
    },

    onChange(e) {
      const { value } = e.target;
      this.message = value;
    },

    textTyping (message, s) {
      if (message.length <= s) {
        this.isGptAnswerMe = false

        if(this.typingTime) {
          clearTimeout(this.typingTime)
          this.typingTime = null
        }

        return
      }
      this.typingTime = setTimeout(() => {
        this.noviceText = this.noviceText + message[s]
        this.textTyping(message, s + 1)
        // clearTimeout(this.typingTime)
      }, 400)
    },

    createConversation (isLoading = true) {
      // wx.showLoading({
      //   title: '加载中',
      //   mask: true
      // })
      this.newChat(isLoading)
    },
    newChat(isLoading) {
      isLoading && (this.loading = true)
      newChat({}).then(res => {
        this.loading = false
        this.$router.push({path: '/home?conversation_id=' + res.data});
        // this.isCreateConversation = true
        // this.conversation_id = res.data

        // if(this.typingTime) {
        //   clearTimeout(this.typingTime)
        //   this.typingTime = null
        // }
        // this.list = []
        // this.noviceText = ''
        // this.isGptAnswerMe = false
        // this.message = ''
      }).catch(err => {
        this.loading = false
        console.log('err', err)
      })
    },
    goToHistory() {
      this.$router.push('/history')
    },
    logout() {
      let that = this
      that.$confirm({
        title: '确定要退出登录吗?',
        okText: '是',
        okType: 'danger',
        cancelText: '否',
        onOk() {
          console.log('OK');
          userLogOut({}).then(res => {
            console.log('res', res)

            that.$store.commit('removeUserName')
            that.$store.commit('removeToken')

            if(that.typingTime) {
              clearTimeout(that.typingTime)
              that.typingTime = null
            }
            that.list = []
            that.conversation_id = ''
            that.isCreateConversation = false
            that.loading = false
            that.noviceText = ''
            that.isGptAnswerMe = false

            that.$message.success('退出登录成功');
          }).catch(err => {
            console.log('err', err)
          })
        },
        onCancel() {
          console.log('Cancel');
        },
      });
    },

    goToLogin() {
      this.$router.push({path: '/login'});
    }
  },
  destroyed() {
    if(this.typingTime) {
      clearTimeout(this.typingTime)
      this.typingTime = null
    }
  }
}
</script>

<style scoped>
@import '../assets/css/reset.css';
.container {
  display: flex;
  flex-direction: column;

  width: 100vw;
  height: 100vh;
}
.header {
  flex: 0 0 4em;
  background-color: var(--medium-green);
}
.username {
  font-size: 1.2rem;
  color: #ffffff;
  cursor: pointer;
}
.main {
  flex: 1;
  /* background-color: var(--brand-green); */
}
.main__inner {
  height: calc(100vh - 8em);
  overflow-y: auto;
}
.main-image {
  display: block;
  width: 2em;
  height: 2em;
  margin-right: 0.625em;
}
.footer {
  flex: 0 0 4em;
  background-color: var(--medium-green);
}

.animate {
  animation: fade 1s infinite forwards;
}

@keyframes fade {
  from {
   opacity: 0;
  }
  to {
   opacity: 1;
  }
}

.loading{
  display: flex;/*让dot和文字在同一行*/
}
.dot{
  /*让点垂直居中*/
    height: 1em;
    line-height: 1;
    /*让点垂直排列*/
    display: flex;
    flex-direction: column;
    /*溢出部分的点隐藏*/
    overflow: hidden;
}
.dot::before{
  /*三行三种点，需要搭配white-space:pre使用才能识别\A字符*/
    content: '...\A..\A.';
    white-space: pre-wrap;
    animation: dot 3s infinite step-end;/*step-end确保一次动画结束后直接跳到下一帧而没有过渡*/
}
@keyframes dot{
    33% {transform: translateY(-2em);}
    66% {transform: translateY(-1em);}
}
</style>
